package com.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BatchCallUtil {

	protected static Logger logger = LoggerFactory.getLogger(BatchCallUtil.class);

	/**
	 * 集合分批次调用方法
	 * @param batchSize
	 * @param list
	 * @param function
	 */
	public static <T, R> void batchCall(Integer batchSize, List<T> list, Function<List<T>, R> function) {
		int totalCount = list.size();
		int batchCount = batchSize;
		int count = totalCount / batchCount;
		int mod = totalCount % batchCount;
		if (mod > 0) {
			count = count + 1;
		}
		if (count == 0) {
			logger.debug("no data to batch");
			return;
		}
		for (int i = 0; i < count; i++) {
			int fromIndex = i * batchSize;
			int toIndex = (i + 1) * batchSize;
			if (i == count - 1) {
				toIndex = totalCount;
			}
			logger.debug("第" + (i + 1) + "次[fromIndex:" + fromIndex + ":toIndex:" + toIndex + "]");
			List<T> subList = list.subList(fromIndex, toIndex);
			function.apply(subList);
		}
	}

	/**
	 * 多次尝试调用方法
	 * @param loopCount
	 * @param function
	 * @param p
	 * @return
	 */
	public static <R, P> R loopCall(Integer loopCount, Function<P, R> function, P p,StringBuffer error) {
		int index = 0;
		while (index < loopCount) {
			try {
				index++;
				R r=function.apply(p);
				error.delete(0, error.length());
				return r;
			} catch (Exception e) {
				e.printStackTrace();
				error.delete(0, error.length());
				error.append(e.getMessage());
				logger.error("循环执行方法错误参数:" + p + "异常信息:" + e.getLocalizedMessage());
			}
		}
		return null;
	}
	
	
	/**
	 * 将集合转换为一维的map
	 * @param list
	 * @param function
	 * @return
	 */
	public static <P> Map<String,P> list2Map(List<P> list,Function<P, String> function){
		Map<String,P> result=new HashMap<String, P>();
		for (P p : list) {
			String key=function.apply(p);
			if(result.containsKey(key)) {
				logger.warn("the key {},has exist in map",key);
			}
			result.put(key, p);
		}
		return result;
	}
	
	/**
	 * 将集合转换为二维的map
	 * @param list
	 * @param function
	 * @return
	 */
	public static <P> Map<String,List<P>> list2MapList(List<P> list,Function<P, String> function){
		Map<String,List<P>> result=new HashMap<String, List<P>>();
		for (P p : list) {
			String key=function.apply(p);
			List<P> sublist=result.get(key);
			if(sublist==null) {
				sublist=new ArrayList<P>();
				result.put(key, sublist);
			}
			sublist.add(p);
		}
		return result;
	}
}
